home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1994 January / PSL Monthly Shareware CD-ROM (Public Software Library) (January 1994).iso / games / dos / puzzles / merlin.com / MERLIN.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-01-16  |  10.0 KB  |  401 lines

  1. ;-------------------------------------------------------------------------
  2. ; MERLIN.ASM
  3. ;
  4. ; 1/15/90
  5. ;
  6. ; David Stafford
  7. ; CIS 72411,2670 or 76666,2542
  8. ;
  9. ; This is heavily hacked code.  Don't take it too seriously.
  10. ;
  11. ; See MERLIN.DOC for usage instructions.
  12. ; Assembled with Turbo Assembler.
  13. ;-------------------------------------------------------------------------
  14.  
  15.         locals
  16. code        segment    para public 'code'
  17.         assume    cs:code,ds:code,es:code,ss:code
  18.         org    100h
  19.  
  20. ;-------------------------------------------------------------------------
  21. ;Store the board at PSP:80h (command line)
  22. ;-------------------------------------------------------------------------
  23.  
  24. Board        equ    80h
  25.  
  26. ;-------------------------------------------------------------------------
  27. ;Window details
  28. ;-------------------------------------------------------------------------
  29.  
  30. COrgX        equ    1            ;client X origin
  31. COrgY        equ    1            ;client Y origin
  32. PaneWidth    equ    6            ;window pane width
  33. PaneHeight    equ    3            ;window pane height
  34. CWidth        equ    PaneWidth*3+2        ;client window width
  35. CHeight        equ    PaneHeight*3+2        ;client window height
  36. FOrgX        equ    COrgX-1            ;frame X origin
  37. FOrgY        equ    COrgY-1            ;frame Y origin
  38. FWidth        equ    CWidth+2        ;frame window width
  39. FHeight        equ    CHeight+2        ;frame window height
  40.  
  41. ;-------------------------------------------------------------------------
  42. ;.COM entry point
  43. ;
  44. ;Ordinarily I put these things at the end of the program (so they don't
  45. ;hang around resident) but this one is small.
  46. ;-------------------------------------------------------------------------
  47.  
  48. Init        proc near
  49.         call    Scramble
  50.  
  51.         mov    ax,3509h        ;get interrupt vector 9
  52.         int    21h            ;(keyboard interrupt)
  53.         mov    word ptr OldInt9,bx
  54.         mov    word ptr OldInt9+2,es
  55.  
  56.         mov    ax,2509h        ;set interrupt vector 9
  57.         mov    dx,offset TSRMain
  58.         int    21h
  59.  
  60.                 mov     dx,offset ResidentEnd
  61.          int    27h            ;terminate and stay resident
  62.         endp
  63.  
  64. ;-------------------------------------------------------------------------
  65. ;Draws the bars in the box frame.
  66. ;
  67. ;Calls DrawLine (in a manner of speaking) twice and falls through.
  68. ;-------------------------------------------------------------------------
  69.  
  70. DrawBars    proc near
  71.         mov    bx,0b3b3h
  72.         mov    dl,0b3h
  73.         mov    ax,offset DrawLine    ;execute DrawLine 3 times
  74.         push    ax
  75.         push    ax
  76.         endp                ;fall through
  77.  
  78. ;-------------------------------------------------------------------------
  79. ;Draws a single line.
  80. ;
  81. ;in: bl = left char, bh = right char, dl = intersection char
  82. ;    es:di points into video   
  83. ;-------------------------------------------------------------------------
  84.  
  85. DrawLine    proc near
  86.         mov    ah,0fh            ;color attribute
  87.         mov    al,bl
  88.         stosw
  89.         mov    cl,CWidth
  90.         mov    al,0c4h            ;horizontal single line
  91.         rep
  92.         stosw
  93.         mov    es:[di-(PaneWidth+1)*2],dl
  94.         mov    es:[di-(PaneWidth+1)*4],dl
  95.         mov    al,bh
  96.         stosw
  97.         add    di,160-FWidth*2        ;point to next line in video
  98.         ret
  99.         endp
  100.  
  101. ;-------------------------------------------------------------------------
  102. ;Int 9 (keyboard interrupt) entry point
  103. ;This routine is modified by Accept, Restore and Init so be careful!
  104. ;-------------------------------------------------------------------------
  105.  
  106. TSRMain        proc near
  107.         sti
  108.         push    ax
  109.         in    al,60h            ;get scan code from keyboard
  110.         cmp    al,50               ;check for 'm' key
  111.         jne    @@Exit            ;no, then exit
  112.         mov    ah,2                ;check shift keys
  113.         int    16h
  114.         and    al,0fh
  115.         cmp    al,4            ;check CTRL key
  116.         je    Accept            ;OK, popup
  117. @@Exit:        pop    ax
  118.         cli
  119. @@ByeByte:    db    0eah            ;intersegment far jump
  120. OldInt9        dd    ?            ;chain to previous int 9 handler
  121.         endp
  122.  
  123. ;-----------------------------------------------------------------------------
  124. ;Gets here when the hotkey has been accepted.
  125. ;Modifies TSRMain.
  126. ;-----------------------------------------------------------------------------
  127.  
  128. Accept        proc near
  129.         cld
  130.  
  131.         push    bx
  132.         push    cx
  133.         push    dx
  134.         push    si
  135.         push    di
  136.         push    ds
  137.         push    es
  138.  
  139.         push    cs            ;ds = cs
  140.         pop    ds
  141.         push    cs            ;es = cs
  142.         pop    es
  143.  
  144.         ;Here I install a short jmp to @@ByeBye in TSRMain
  145.         mov    word ptr TSRMain,12ebh
  146.         endp                ;fall through
  147.  
  148. ;-----------------------------------------------------------------------------
  149. ;Resets the keyboard and signals end-of-interrupt to the 8259
  150. ;-----------------------------------------------------------------------------
  151.  
  152. ResetKeyboard    proc near
  153.         in    al,61h            ;get current control port value
  154.         push    ax            ;save it
  155.         or    al,80h            ;set bit 7
  156.         out    61h,al            ;send reset value
  157.         pop    ax            ;restore control port value
  158.         out    61h,al            ;enable keyboard
  159.         cli
  160.         mov    ax,0f20h        ;al = get EOI value
  161.                         ;ah = get video mode (below)
  162.         out    20h,al            ;send EOI to 8259
  163.         sti
  164.         endp                ;fall through
  165.  
  166. ;-----------------------------------------------------------------------------
  167. ;Gets the video mode and saves the video buffers
  168. ;
  169. ;The strange looking segment address (0b03fh) for the video screen lets
  170. ;me assume an offset of zero for some accesses (saves a couple bytes).
  171. ;-----------------------------------------------------------------------------
  172.  
  173. GetVideo    proc near
  174.         int    10h            ;get the video mode (assume ah = 0fh)
  175.                         ;bh = video page
  176.         mov    dx,0b03fh        ;assume mono
  177.         cmp    al,7            ;is it mono?
  178.         je    @@GotSegment
  179.         cmp    al,2            ;color?
  180.         je    @@GetPage
  181.         cmp    al,3            ;color?
  182.         jne    BadVideo        ;bad video mode, don't pop up!
  183.  
  184. @@GetPage:    mov    dh,0b8h            ;set for color
  185.         add    dh,bh            ;add the page
  186.  
  187. @@GotSegment:    mov    ds,dx            ;get video segment
  188.  
  189.         mov    ah,3            ;bh = video page
  190.         int    10h                  ;get cursor shape & position
  191.           push    cx            ;save cursor shape
  192.  
  193.         mov    ch,20h
  194.         mov    ah,1            ;hide cursor
  195.         int    10h            ;set cursor shape
  196.  
  197.         xor    si,si            ;offset into video screen
  198.         mov    di,offset VideoBuf
  199.         mov    bx,FHeight        ;bx = loop variable
  200.  
  201. @@NextLine:    mov    cx,FWidth
  202.         rep
  203.         movsw
  204.  
  205.         add    si,160-FWidth*2        ;point to next line in video
  206.         dec    bx
  207.         jnz    @@NextLine
  208.  
  209.         push    ds            ;es = ds (video page)
  210.         pop    es
  211.         push    cs            ;ds = cs
  212.         pop    ds
  213.         endp                ;fall through
  214.  
  215. ;-----------------------------------------------------------------------------
  216. ;Draws the box frame
  217. ;-----------------------------------------------------------------------------
  218.  
  219. DrawFrame    proc near
  220.         xor    di,di            ;offset into video screen
  221.  
  222.         mov    bx,0bfdah
  223.         mov    dx,03c2h        ;dh is loop counter
  224.         jmp    short @@Doit
  225.  
  226. @@Top:        mov    bx,0b4c3h
  227.         mov    dl,0c5h
  228.  
  229. @@DoIt:        call    DrawLine
  230.         call    DrawBars
  231.  
  232.         dec    dh
  233.         jnz    @@Top
  234.  
  235.         mov    bx,0d9c0h
  236.         mov    dl,0c1h
  237.         call    DrawLine
  238.         jmp    short DrawClient
  239.         endp
  240.  
  241. ;-------------------------------------------------------------------------
  242. ;Restores the video buffer
  243. ;Modifies TSRMain.
  244. ;-------------------------------------------------------------------------
  245.  
  246. Restore        proc near
  247.         xor    di,di            ;offset into video screen
  248.         mov    si,offset VideoBuf
  249.         mov    bl,FHeight        ;bx = counter, assume bh = 0
  250. @@NextLine:
  251.         mov    cl,FWidth        ;assume ch = 0
  252.         rep
  253.         movsw
  254.         add    di,160-FWidth*2        ;point to next line in video
  255.         dec    bx
  256.         jnz    @@NextLine
  257.  
  258.         mov    ah,1
  259.         pop    cx            ;restore cursor shape
  260.         int    10h
  261.  
  262.         ;Arrive here if in graphics mode.
  263.         ;Uninstall the short jmp to @@ByeBye in TSRMain.
  264. BadVideo:    mov    word ptr TSRMain,050fbh
  265.  
  266.         pop    es            ;exit
  267.         pop    ds
  268.         pop    di
  269.         pop    si
  270.         pop    dx
  271.         pop    cx
  272.         pop    bx
  273.         pop    ax
  274.         iret
  275.         endp
  276.  
  277. ;-------------------------------------------------------------------------
  278. ;Scrambles the game board
  279. ;-------------------------------------------------------------------------
  280.  
  281. Scramble    proc near
  282.         push    ds
  283.         mov    ds,dx            ;assume dx = 0
  284.         mov    ax,ds:[46ch]        ;get timer (random number)
  285.         pop    ds
  286.  
  287.         mov    bl,Board+1        ;assume bh = 0
  288.         mov    cl,9            ;loop counter (assume ch = 0)
  289.                         
  290. @@Top:        xor    dl,dl
  291.         shr    ax,1
  292.         adc    dl,dl
  293.         mov    [bx],dl
  294.         inc    bx
  295.         loop    @@Top
  296.         ret
  297.         endp
  298.  
  299. ;-------------------------------------------------------------------------
  300. ;Jump here when you want to scramble the board and return to DrawClient
  301. ;-------------------------------------------------------------------------
  302.  
  303. ScrambleKey    proc near
  304.         call    Scramble
  305.         endp                ;fall through
  306.  
  307. ;-----------------------------------------------------------------------------
  308. ;Draws the individual squares
  309. ;-----------------------------------------------------------------------------
  310.  
  311. DrawClient    proc near
  312.         mov    dx,Board+1        ;damn, can't assume dh = 0
  313.         mov    di,(CHeight*80+COrgX)*2    ;offset into video screen
  314.       
  315.         mov    cl,3
  316. @@Top:        push    cx
  317.         mov    bl,3
  318. @@Top1:        mov    si,dx
  319.         mov    bh,3
  320. @@Top2:        mov    ax,7020h        ;char/attribute
  321.         mov    cl,[si]
  322.         jcxz    @@0            ;assume ch = 0
  323.         cbw                ;ah = 0
  324. @@0:        mov    cl,6
  325.         rep
  326.         stosw
  327.         inc    si            ;next square
  328.         inc    di            ;skip video column
  329.         inc    di
  330.         dec    bh
  331.         jnz    @@Top2
  332.         sub    di,160+CWidth*2+2    ;move up a row
  333.         dec    bx            ;assume bh = 0
  334.         jnz    @@Top1
  335.         sub    di,160
  336.         mov    dx,si
  337.  
  338.         pop    cx
  339.         loop    @@Top
  340.         endp                ;fall through
  341.  
  342. ;-----------------------------------------------------------------------------
  343. ;Gets a keypress and performs the desired action
  344. ;-----------------------------------------------------------------------------
  345.  
  346. GetKey        proc near
  347.         cbw                ;assume al < 128
  348.         cwd                ;dx = 0
  349.         int    16h            ;get keypress
  350.         cmp    al,27            ;escape?
  351.         je    Restore
  352.         cmp    al,13
  353.         je    ScrambleKey
  354.  
  355.         sub    al,'0'
  356.         cmp    al,9
  357.         ja    GetKey
  358.  
  359.         mov    dl,al
  360.         mov    bx,offset Keys-1
  361.         xlat
  362.         mov    bx,Board+1
  363.         mov    cl,9
  364.  
  365. @@ToggleLoop:    dec    dx            ;assume dh = 0
  366.         jz    @@Toggle
  367.         shr    al,1
  368.         jnc    @@Bottom
  369. @@Toggle:    xor    byte ptr [bx],1
  370. @@Bottom:    inc    bx
  371.         loop    @@ToggleLoop
  372.         jmp    short DrawClient
  373.         endp
  374.  
  375. ;-------------------------------------------------------------------------
  376. ;Data
  377. ;-------------------------------------------------------------------------
  378.  
  379. ;Bitmaps for which keys affect which squares.  Only 8 bits for each
  380. ;square because we assume key X toggles square X.  Otherwise we would
  381. ;have to use 9 more bytes for this table and the added logic is less
  382. ;than 9 bytes.
  383.  
  384. Keys        db    00001101b        ;1
  385.         db    00000011b        ;2
  386.         db    00011010b        ;3
  387.         db    00100001b        ;4
  388.         db    01011010b        ;5
  389.         db    10000100b        ;6
  390.         db    01011000b        ;7
  391.         db    11000000b        ;8
  392.         db    10110000b        ;9
  393.  
  394. ;Video save area
  395.  
  396. VideoBuf    label    byte                ;screen save area
  397. ResidentEnd    equ    offset VideoBuf + FWidth * FHeight * 2
  398.  
  399.         ends
  400.         end Init
  401.